/**
 * Copyright(C): CETC-32
 * @Title: GlobalExceptionHandler
 * @Description: 全局异常捕获与处理
 * @author: youqing
 * @version: 1.0
 * @date: 2020/9/11 10:55
 * 更改描述：
 */

package com.cetc32.dh.common.response;
import com.auth0.jwt.exceptions.TokenExpiredException;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;

//捕获全局异常的处理
/**
 * Token检查类
 * @Title: FormFilter
 * @version: 1.0
 * @date: 2020/9/11 10:55
 */
//@RestControllerAdvice
public class GlobalExceptionHandler {


    // 捕捉shiro的异常
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(ShiroException.class)
    public ResponseResult handle401(ShiroException e) {
        return ResponseResult.fail(401, e.getMessage(), null);
    }

    // 捕捉未登录的异常
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(UnauthenticatedException.class)
    public ResponseResult handle401(UnauthenticatedException e) {
        System.out.println(e.getMessage());
        return ResponseResult.fail(401, "你还没有登录", null);
    }

    // 捕捉没有相应的权限或者角色的异常
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(UnauthorizedException.class)
    public ResponseResult handle401(UnauthorizedException e) {
        System.out.println(e.getMessage());
        return ResponseResult.fail(401, "你没有权限访问"+e.getMessage(), null);
    }


    /**
     * @Validated 校验错误异常处理
     */
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseResult handler(MethodArgumentNotValidException e) throws IOException {
//        log.error("运行时异常:-------------->",e);
        BindingResult bindingResult = e.getBindingResult();
        //这一步是把异常的信息最简化
        ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();
        return ResponseResult.fail(HttpStatus.BAD_REQUEST.value(),objectError.getDefaultMessage(),null);
    }

    /**
     * 处理Assert的异常
     */
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = IllegalArgumentException.class)
    public ResponseResult handler(IllegalArgumentException e) throws IOException {
//        log.error("Assert异常:-------------->{}",e.getMessage());
        return ResponseResult.fail(400,e.getMessage(),null);
    }


    //运行时错误处理
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = RuntimeException.class)
    public ResponseResult handle(RuntimeException e){
        return ResponseResult.fail(HttpStatus.BAD_REQUEST.value(),e.getMessage(),null);
    }

    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = TokenExpiredException.class)
    public ResponseResult handler(TokenExpiredException e) throws IOException {
        return ResponseResult.fail(HttpStatus.BAD_REQUEST.value(),"token已经过期，请重新登录",null);
    }
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     * 修改信息：
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(value= HttpRequestMethodNotSupportedException.class)
    public ResponseResult handler405(HttpRequestMethodNotSupportedException e){
        return ResponseResult.fail(HttpStatus.METHOD_NOT_ALLOWED.value(),"方法不支持的請求方式",null);
    }
}
